package com.le.tester.imooc.masterJUC.lock.deadlock;

import org.apache.ibatis.parsing.TokenHandler;

/**
 * 描述：转账得时候发生了死锁
 */
public class TransferMoney implements Runnable {

    private static Account a = new Account(500);
    private static Account b = new Account(500);

    private static final Object lock = new Object();
    private int flag = 1;

    public static void main(String[] args) throws InterruptedException {
        TransferMoney transferMoney0 = new TransferMoney();
        TransferMoney transferMoney1 = new TransferMoney();
        transferMoney0.flag = 0;
        transferMoney1.flag = 1;
        Thread thread = new Thread(transferMoney0);
        Thread thread1 = new Thread(transferMoney1);
        thread.start();
        thread1.start();
        thread.join();
        thread1.join();
        System.out.println("a balance is " + a.balance);
        System.out.println("b balance is " + b.balance);
    }

    @Override
    public void run() {

        if (flag == 1) {
            transferMoney(a, b, 200);
        }
        if (flag == 0) {
            transferMoney(b, a, 200);
        }
    }

    public static void transferMoney(Account from, Account to, int amount) {

        class Helper {
            public void transfer() {
                if (from.balance - amount < 0) {
                    System.out.println("余额不足，转账失败！");
                    return;
                }
                from.balance -= amount;
                to.balance += amount;
                System.out.println("成功转账：" + amount);
            }

        }
        synchronized (from) {
            try {
                Thread.sleep(500);
            } catch (InterruptedException e) {
                System.out.println(e.getMessage());
            }
            synchronized (to) {
                if (from.balance - amount < 0) {
                    System.out.println("余额不足，转账失败！");
                    return;
                }
                from.balance -= amount;
                to.balance += amount;
                System.out.println("成功转账：" + amount);
            }
        }
        //获取汇款方和收款方的hash值
        int fromHash = System.identityHashCode(from);
        int toHash = System.identityHashCode(to);
        if (fromHash < toHash) {
            synchronized (from) {
                synchronized (to) {
                    new Helper().transfer();
                }
            }
        } else if (fromHash > toHash) {
            synchronized (to) {
                synchronized (from) {
                    new Helper().transfer();
                }
            }
        } else {
            synchronized (lock){
                synchronized (from) {
                    synchronized (to) {
                        new Helper().transfer();
                    }
                }
            }

        }
    }

    static class Account {
        int balance;

        public Account(int balance) {
            this.balance = balance;
        }
    }
}
